home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / bind493a.zip / res / getnetnamadr.c < prev    next >
C/C++ Source or Header  |  1995-06-29  |  8KB  |  288 lines

  1. /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
  2.  *    Dep. Matematica Universidade de Coimbra, Portugal, Europe
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software for any
  5.  * purpose with or without fee is hereby granted, provided that the above
  6.  * copyright notice and this permission notice appear in all copies.
  7.  */
  8. /*
  9.  * Copyright (c) 1983, 1993
  10.  *    The Regents of the University of California.  All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  * 3. All advertising materials mentioning features or use of this software
  21.  *    must display the following acknowledgement:
  22.  *    This product includes software developed by the University of
  23.  *    California, Berkeley and its contributors.
  24.  * 4. Neither the name of the University nor the names of its contributors
  25.  *    may be used to endorse or promote products derived from this software
  26.  *    without specific prior written permission.
  27.  *
  28.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38.  * SUCH DAMAGE.
  39.  */
  40.  
  41. #if defined(LIBC_SCCS) && !defined(lint)
  42. static char sccsid[] = "@(#)getnetbyaddr.c    8.1 (Berkeley) 6/4/93";
  43. static char sccsid_[] = "from getnetnamadr.c    1.4 (Coimbra) 93/06/03";
  44. static char rcsid[] = "$Id: getnetnamadr.c,v 8.4 1995/06/29 09:26:28 vixie Exp $";
  45. #endif /* LIBC_SCCS and not lint */
  46.  
  47. #include <sys/param.h>
  48. #include <sys/socket.h>
  49. #include <netinet/in.h>
  50. #include <arpa/inet.h>
  51. #include <arpa/nameser.h>
  52.  
  53. #include <stdio.h>
  54. #include <netdb.h>
  55. #include <resolv.h>
  56. #include <ctype.h>
  57. #include <errno.h>
  58. #include <string.h>
  59.  
  60. extern int h_errno;
  61.  
  62. #if defined(mips) && defined(SYSTYPE_BSD43)
  63. extern int errno;
  64. #endif
  65.  
  66. struct netent *_getnetbyaddr __P((long net, int type));
  67. struct netent *_getnetbyname __P((const char *name));
  68.  
  69. #define BYADDR 0
  70. #define BYNAME 1
  71. #define    MAXALIASES    35
  72.  
  73. #if PACKETSZ > 1024
  74. #define    MAXPACKET    PACKETSZ
  75. #else
  76. #define    MAXPACKET    1024
  77. #endif
  78.  
  79. typedef union {
  80.     HEADER    hdr;
  81.     u_char    buf[MAXPACKET];
  82. } querybuf;
  83.  
  84. typedef union {
  85.     long    al;
  86.     char    ac;
  87. } align;
  88.  
  89. static struct netent *
  90. getnetanswer(answer, anslen, net_i)
  91.     querybuf *answer;
  92.     int anslen;
  93.     int net_i;
  94. {
  95.  
  96.     register HEADER *hp;
  97.     register u_char *cp;
  98.     register int n;
  99.     u_char *eom;
  100.     int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
  101.     char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
  102.         *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
  103. static    struct netent net_entry;
  104. static    char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
  105.  
  106.     /*
  107.      * find first satisfactory answer
  108.      *
  109.      *      answer --> +------------+  ( MESSAGE )
  110.      *           |   Header   |
  111.      *           +------------+
  112.      *           |  Question  | the question for the name server
  113.      *           +------------+
  114.      *           |   Answer   | RRs answering the question
  115.      *           +------------+
  116.      *           | Authority  | RRs pointing toward an authority
  117.      *           | Additional | RRs holding additional information
  118.      *           +------------+
  119.      */
  120.     eom = answer->buf + anslen;
  121.     hp = &answer->hdr;
  122.     ancount = ntohs(hp->ancount); /* #/records in the answer section */
  123.     qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
  124.     bp = netbuf;
  125.     buflen = sizeof(netbuf);
  126.     cp = answer->buf + HFIXEDSZ;
  127.     if (!qdcount) {
  128.         if (hp->aa)
  129.             h_errno = HOST_NOT_FOUND;
  130.         else
  131.             h_errno = TRY_AGAIN;
  132.         return (NULL);
  133.     }
  134.     while (qdcount-- > 0)
  135.         cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  136.     ap = net_aliases;
  137.     *ap = NULL;
  138.     net_entry.n_aliases = net_aliases;
  139.     haveanswer = 0;
  140.     while (--ancount >= 0 && cp < eom) {
  141.         n = dn_expand(answer->buf, eom, cp, bp, buflen);
  142.         if (n < 0)
  143.             break;
  144.         cp += n;
  145.         ans[0] = '\0';
  146.         (void)strcpy(&ans[0], bp);
  147.         GETSHORT(type, cp);
  148.         GETSHORT(class, cp);
  149.         cp += INT32SZ;        /* TTL */
  150.         GETSHORT(n, cp);
  151.         if (class == C_IN && type == T_PTR) {
  152.             n = dn_expand(answer->buf, eom, cp, bp, buflen);
  153.             if (n < 0) {
  154.                 cp += n;
  155.                 return (NULL);
  156.             }
  157.             cp += n; 
  158.             *ap++ = bp;
  159.             bp += strlen(bp) + 1;
  160.             net_entry.n_addrtype =
  161.                 (class == C_IN) ? AF_INET : AF_UNSPEC;
  162.             haveanswer++;
  163.         }
  164.     }
  165.     if (haveanswer) {
  166.         *ap = NULL;
  167.         switch (net_i) {
  168.         case BYADDR:
  169.             net_entry.n_name = *net_entry.n_aliases;
  170.             net_entry.n_net = 0L;
  171.             break;
  172.         case BYNAME:
  173.             in = *net_entry.n_aliases;
  174.             net_entry.n_name = &ans[0];
  175.             aux2[0] = '\0';
  176.             for (i = 0; i < 4; i++) {
  177.                 for (st = in, nchar = 0;
  178.                      *st != '.';
  179.                      st++, nchar++)
  180.                     ;
  181.                 if (nchar != 1 || *in != '0' || flag) {
  182.                     flag = 1;
  183.                     (void)strncpy(paux1,
  184.                               (i==0) ? in : in-1,
  185.                               (i==0) ?nchar : nchar+1);
  186.                     paux1[(i==0) ? nchar : nchar+1] = '\0';
  187.                     pauxt = paux2;
  188.                     paux2 = strcat(paux1, paux2);
  189.                     paux1 = pauxt;
  190.                 }
  191.                 in = ++st;
  192.             }          
  193.             net_entry.n_net = inet_network(paux2);
  194.             break;
  195.         }
  196.         net_entry.n_aliases++;
  197.         return (&net_entry);
  198.     }
  199.     h_errno = TRY_AGAIN;
  200.     return (NULL);
  201. }
  202.  
  203. struct netent *
  204. getnetbyaddr(net, net_type)
  205.     register long net;
  206.     register int net_type;
  207. {
  208.     unsigned int netbr[4];
  209.     int nn, anslen;
  210.     querybuf buf;
  211.     char qbuf[MAXDNAME];
  212.     unsigned long net2;
  213.     struct netent *net_entry;
  214.  
  215.     if (net_type != AF_INET)
  216.         return (_getnetbyaddr(net, net_type));
  217.  
  218.     for (nn = 4, net2 = net; net2; net2 >>= 8)
  219.         netbr[--nn] = net2 & 0xff;
  220.     switch (nn) {
  221.     case 3:     /* Class A */
  222.         sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
  223.         break;
  224.     case 2:     /* Class B */
  225.         sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
  226.         break;
  227.     case 1:     /* Class C */
  228.         sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
  229.             netbr[1]);
  230.         break;
  231.     case 0:     /* Class D - E */
  232.         sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
  233.             netbr[1], netbr[0]);
  234.         break;
  235.     }
  236.     anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
  237.     if (anslen < 0) {
  238. #ifdef DEBUG
  239.         if (_res.options & RES_DEBUG)
  240.             printf("res_query failed\n");
  241. #endif
  242.         if (errno == ECONNREFUSED)
  243.             return (_getnetbyaddr(net, net_type));
  244.         return (NULL);
  245.     }
  246.     net_entry = getnetanswer(&buf, anslen, BYADDR);
  247.     if (net_entry) {
  248.         unsigned u_net = net;    /* maybe net should be unsigned ? */
  249.  
  250.         /* Strip trailing zeros */
  251.         while ((u_net & 0xff) == 0 && u_net != 0)
  252.             u_net >>= 8;
  253.         net_entry->n_net = u_net;
  254.         return (net_entry);
  255.     }
  256.     return (_getnetbyaddr(net, net_type));
  257. }
  258.  
  259. struct netent *
  260. getnetbyname(net)
  261.     register const char *net;
  262. {
  263.     int anslen;
  264.     querybuf buf;
  265.     char qbuf[MAXDNAME];
  266.     struct netent *net_entry;
  267.  
  268.     if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
  269.         h_errno = NETDB_INTERNAL;
  270.         return (NULL);
  271.     }
  272.     strcpy(&qbuf[0], net);
  273.     anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
  274.     if (anslen < 0) {
  275. #ifdef DEBUG
  276.         if (_res.options & RES_DEBUG)
  277.             printf("res_query failed\n");
  278. #endif
  279.         if (errno == ECONNREFUSED)
  280.             return (_getnetbyname(net));
  281.         return (_getnetbyname(net));
  282.     }
  283.     net_entry = getnetanswer(&buf, anslen, BYNAME);
  284.     if (net_entry)
  285.         return (net_entry);
  286.     return (_getnetbyname(net));
  287. }
  288.